

fn main() {
    #[derive(Debug)]
    enum IpAddrKind {
        V4,
        V6,
    }
    
    let four = IpAddrKind::V4;
    let six = IpAddrKind::V6;

    println!("{:?}", four);
    println!("{:?}", six);
    
    fn route(ip_kind: IpAddrKind) {
        println!("{:?}", ip_kind);
    }
    
    route(IpAddrKind::V4);
    route(IpAddrKind::V6);

    struct IpAddr {
        kind: IpAddrKind,
        address: String,
    }
    
    let home = IpAddr {
        kind: IpAddrKind::V4,
        address: String::from("127.0.0.1"),
    };
    
    let loopback = IpAddr {
        kind: IpAddrKind::V6,
        address: String::from("::1"),
    };

    println!("{:?},{}", home.kind, home.address);
    println!("{:?},{}", loopback.kind, loopback.address);
    
    
    enum Message{
        Quit,
        Move { x: i32, y: i32 },
        Write(String),
        ChangeColor(i32, i32, i32),
    }
    
    impl Message {
        fn call(&self) {
            match self {
                Message::Quit => println!("quit "),
                Message::Move{x, y} => println!("move to x:{}, y:{}", x, y),
                Message::Write(s) => println!("write {}", s),
                Message::ChangeColor(r, g, b) => println!("change color to r:{}, g:{}, b:{}", r, g, b),
            }
            
        }
    }
    
    let w = Message::Write(String::from("hello"));
    w.call();

    let cc = Message::ChangeColor(255, 0, 255);
    cc.call();

    let m = Message::Move{x: 1, y: 2};
    m.call();

    let q = Message::Quit;
    q.call();

    let some_number = Some(5);
    let some_string = Some("a string");
    // None 赋值需要指明类型
    let absent_number: Option<i32> = None;

    match some_number {
        Some(i) => println!("{}", i),
        None => (),
    };

    match some_string {
        Some(s) => println!("{}", s),
        None => (),
    };

    match absent_number {
        Some(i) => println!("{}", i),
        None => (),
    };

    let test_coin = Coin::Quarter(UsState::Alabama);

    println!("{}", value_in_cents(test_coin));

    let five = Some(5);
    let six = plus_one(five);
    let none = plus_one(None);

    println!("{:?}, {:?}", six, none);

    let some_u8_value = 0u8;
    match some_u8_value {
        1 => println!("one"),
        3 => println!("three"),
        5 => println!("five"),
        7 => println!("seven"),
        _ => println!("error"),
    }

    let some_u8_value = Some(3u8);

    match some_u8_value {
        Some(3) => println!("three"),
        _ => (),
    }
    let some_u8_value = Some(9u8);
    //如下代码等价于上面代码
    if let Some(3) = some_u8_value {
        println!("three");
    }

    let mut count = 0;
    let state = UsState::Alabama;
    let coin = Coin::Penny;
    if let Coin::Quarter(state) = coin {
        match state {
            UsState::Alabama => println!("State quarter from Alabama!"),
            _ => println!("State quarter from Alaska!"),
        };

    }else{
        count += 1;
    }

    println!("count:{}", count);

}


enum UsState{
    Alabama,
    Alaska,
}

enum Coin{
    Penny,
    Nickel,
    Dime,
    // 枚举 中加入 一个枚举
    Quarter(UsState),
}

fn value_in_cents(coin: Coin) -> u8 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter(state) => {
            match state {
                UsState::Alabama => println!("State quarter from Alabama!"),
                _ => println!("State quarter from Alaska!"),
            };
            
            25
        }
    }
}

fn plus_one(x: Option<i32>) -> Option<i32> {
    match x {
        
        None => None,
        Some(i) => Some(i + 1),
    }
}
